use std::collections::HashMap;

// insert_command.rs
use anyhow::Error;
use crate::{db::{Db, Vector}, frame::Frame, tools::optimized_norm};

#[derive(Debug)]
pub struct Insert {
    collection_name: String,
    id: String,
    metadata: HashMap<String, String>,
    vector: Vec<f32>,
}

impl Insert {
    pub fn parse_from_frame(frame: Frame) -> Result<Self, Error> {
        let mut args = frame.get_args().into_iter();
        
        // Skip command name
        args.next().ok_or_else(|| Error::msg("Missing command"))?;

        let collection_name_arg = args.next();
        let collection_name = match collection_name_arg {
            Some(name) => name,
            None => {
                return Err(Error::msg("Missing collection name"));
            }
        };

        let id_arg = args.next();
        let id = match id_arg {
            Some(id_str) => id_str,
            None => {
                return Err(Error::msg("Missing ID"));
            }
        };

        // Parse vector components
        let mut vector = Vec::new();
        let mut found_metadata = false;
        
        while let Some(arg) = args.next() {
            if arg.eq_ignore_ascii_case("METADATA") {
                found_metadata = true;
                break;
            }
            
            let num = arg.parse::<f32>()
                .map_err(|_| Error::msg(format!("Invalid float value: {}", arg)))?;
            vector.push(num);
        }

        if vector.is_empty() {
            return Err(Error::msg("Vector cannot be empty"));
        }

        // Parse metadata
        let mut metadata = HashMap::new();
        if found_metadata {
            let remaining_args: Vec<_> = args.collect();
            
            if remaining_args.len() % 2 != 0 {
                return Err(Error::msg("METADATA requires even number of key-value arguments"));
            }

            for chunk in remaining_args.chunks_exact(2) {
                metadata.insert(chunk[0].clone(), chunk[1].clone());
            }
        }

        Ok(Self {
            collection_name,
            id,
            metadata,
            vector,
        })
    }

    pub fn apply(self, db: &mut Db) -> Result<Frame, Error> {
        
        let collection = match db.collections.get_mut(&self.collection_name) {
            Some(c) => c,
            None => {
                return Err(Error::msg(
                    format!("Collection '{}' does not exist", self.collection_name)
                ));
            }
        };

        if self.vector.len() != collection.dimension {
            return Err(Error::msg(
                format!("Vector dimension mismatch (expected {}, found {})",
                collection.dimension, // 维度
                self.vector.len()
            )));
        }

        if collection.vectors.contains_key(&self.id) {
            return Err(Error::msg(format!("ID '{}' already exists", self.id)));
        }

        let norm = optimized_norm(self.vector.iter().copied());
        let vector = Vector { metadata: self.metadata, vector: self.vector, norm};
        collection.vectors.insert(self.id, vector);
        Ok(Frame::Ok)
    }
}